import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState, } from "react";
import { Input, Select } from "antd";
import { SelectBox } from "devextreme-react";
import { consts } from "../../../../../tools/consts";
import { SearchOutlined } from "@ant-design/icons";
import { CpasIcon, DevGrid } from "~/public/cpas-ui";
import { getYears } from "../../../../../tools/Tools";
import { dbname } from "../../../classes/HandSonGridToolService/pubDbname";
import { getColumnHeader, getTableData, } from "./DataService";
import { useBaseReportFilterData } from "./DataFilterService";
import { devCellScrollPositionBySelected, devCellSelected, resetScrollView, } from "../../../classes/DevTableService";
import { DataGridOptions } from "./CommonOption";
export const dynamic_BB_REPORT_Column = {
    // common: [
    //   "主键",
    //   "账套ID",
    //   "项目编号",
    //   "项目名称",
    //   "方向",
    //   "合计项级别",
    //   "是否关键账户",
    // ],
    common: ["主键", "项目名称"],
    资产负债表: ["审定数"],
    利润表: ["本期审定发生额"],
};
export const dynamic_CW_KMB_Column = {
    // common: ["主键", "账套ID", "科目编号", "科目名称", "科目方向", "币种"],
    common: ["主键", "科目名称", "科目类型"],
    资产: ["期末审定数"],
    负债: ["期末审定数"],
    利润: ["本期审定发生额"],
};
// 报告基础数据名称
export const BB_REPORT = "base.reportItems";
// 科目审定表名称
export const CW_KMB = "base.subjectSDB";
/**
 * 该组件的数据同步由两部分组成
 * initBaseReportData,取后台数据。依赖 tableName ,  year , devCoords的 rmap 定位
 * filterData 前端数据源过滤依赖, category , isDynamic , datasource
 * @param props
 * @param ref
 * @constructor
 */
const BaseReportTabPanel = (props, ref) => {
    const devTableRef = useRef(null);
    // state---------------------------------
    const yearData = consts.YearTagList;
    /**
     * 数据源
     */
    // 所属报表类型 option, 用于报表项目基础数据
    const [fromBaseReportCategoryOption, setFromBaseReportCategoryOption] = useState([
        { label: "资产负债表", value: "资产负债表" },
        { label: "利润表", value: "利润表" },
    ]);
    // 科目类型 用于科目审定明细表
    const [kmLxOption, setKmLxOption] = useState([
        { label: "资产", value: "资产" },
        { label: "负债", value: "负债" },
        { label: "利润", value: "利润" },
    ]);
    /**
     * 搜索条件
     */
    // 项目名称受控组件模式,避免高频刷新
    const projectSearchInputRef = useRef(null);
    // 取数源下拉框选中值
    const [searchTableName, setSearchTableName] = useState("base.reportItems");
    // 年度条件当前值
    const [searchYear, setSearchYear] = useState(consts.ThisYear);
    // 所属报表
    const [searchCategory, setSearchCategory] = useState("资产负债表");
    // 公式坐标,目前仅会从父元素触发. 做状态回显,定位单元格. 当为null时说明没有选择公式，不需要定位
    const [formulaCoords, setFormulaCoords] = useState({
        tname: null,
        rmap: null,
        cmap: null,
        year: null,
    });
    // 记录上一次定位条件, 用于来决定是否要执行定位. 只有当以下数据变化的时候,才触发重新定位.
    // 以当前表渲染的数据为条件, 假如修改公式坐标, 不需要重新定位.
    // const prevDevPosition = useRef<any>({
    //   filterData,
    // });
    /**
     * 表体数据
     */
    const [baseReportData, setBaseReportData] = useState({
        dataSource: [],
        columns: [],
    });
    /**
     * 计算数据
     * React内部数据流，决定行列显示
     * searchCategory 自定义分类变化
     * isDynamic 开启动态模式
     * baseReportData 每当基础数据有变化的时候
     */
    const filterData = useBaseReportFilterData(baseReportData, searchCategory, props.dynamic, searchTableName);
    console.log("数据定位--- filterData");
    /**
     * 获取项目下拉框数据
     */
    const getProjectSearchValue = () => {
        return projectSearchInputRef.current?.input.value || "";
    };
    // 同步1
    // 初始化同步搜索条件下拉框数据源
    useEffect(() => {
        initData().then((r) => () => {
            console.log("初始化数据完成");
        });
        return () => {
            console.log("组件销毁");
        };
    }, [props.baseReportCategoryData]);
    useEffect(() => {
        // 如果没有指定rmap的定位则走默认的切换
        const { dynmiacType, isDynamic, dynamicModel } = props.dynamic;
        // if (formulaCoords.rmap) {
        //   return;
        // }
        let options = [];
        if (searchTableName === BB_REPORT) {
            if (dynmiacType === "pt" && dynamicModel && isDynamic) {
                options = [{ label: "资产负债表", value: "资产负债表" }];
            }
            else if (dynmiacType === "pd" && dynamicModel && isDynamic) {
                options = [{ label: "利润表", value: "利润表" }];
            }
            else {
                options = [
                    { label: "资产负债表", value: "资产负债表" },
                    { label: "利润表", value: "利润表" },
                ];
            }
            setFromBaseReportCategoryOption(options);
        }
        else {
            if (dynmiacType === "pt" && dynamicModel && isDynamic) {
                options = [
                    { label: "资产", value: "资产" },
                    { label: "负债", value: "负债" },
                ];
            }
            else if (dynmiacType === "pd" && dynamicModel && isDynamic) {
                options = [{ label: "利润", value: "利润" }];
            }
            else {
                options = [
                    { label: "资产", value: "资产" },
                    { label: "负债", value: "负债" },
                    { label: "利润", value: "利润" },
                ];
            }
            setKmLxOption(options);
        }
        // 如果非动态模式的情况下 ,  走普通公式定位
        if (dynamicModel && isDynamic) {
            // 动态公式模式,业务限定为本年和
            setSearchYear(consts.ThisYear);
            setSearchCategory(options[0].value);
        }
        else {
            // TODO 非动态公式模式，需要解析普通公式. 重新设置上面的两个条件
        }
    }, [searchTableName, props.dynamic, formulaCoords]);
    /**
     * 监听数据变化
     */
    // 同步2
    // 表格后台表格数据
    // 依赖表名 , 年度的变化都会进行后台数据请求
    // formulaCoords 用于定位设置 category 搜索条件, 当 formulaCoords的 rmap 存在, 则表示需要定位category.
    useEffect(() => {
        if (searchTableName) {
            initBaseReportData();
        }
    }, [searchTableName, searchYear, formulaCoords]);
    // 同步3
    // 根据公式,同步滚动条位置
    useEffect(() => {
        // dev bug 补丁 , 在开启虚拟化的情况下, 切换数据源必须重置表格的滚动条. 否则会出现白屏
        resetScrollView(devTableRef);
        if (formulaCoords.rmap &&
            (formulaCoords.year === searchYear || formulaCoords.year === "year") &&
            formulaCoords.tname === searchTableName) {
            // 延时300更稳定, dev表格的渲染在收到useEffect,可能还没渲染完成. 这是dev自身的问题
            // setTimeout(() => {
            //   console.log("数据定位---开始滚动定位");
            //   devCellScrollPositionBySelected(
            //     devTableRef,
            //     formulaCoords.rmap,
            //     formulaCoords.cmap,
            //     filterData,
            //     DataGridOptions.columnWidth
            //   );
            // }, 300);
        }
    }, [
        baseReportData,
        searchYear,
        searchCategory,
        searchTableName,
        props.dynamic,
    ]);
    // 同步4
    // 同步单元格选中状态
    const onContentReadyCallBack = useCallback(async () => {
        if (formulaCoords.rmap &&
            (formulaCoords.year === searchYear || formulaCoords.year === "year") &&
            formulaCoords.tname === searchTableName) {
            console.log("数据定位---单元格标注");
            devCellSelected(devTableRef, formulaCoords.rmap, formulaCoords.cmap, DataGridOptions.columnWidth);
        }
    }, [
        formulaCoords.rmap,
        formulaCoords.cmap,
        formulaCoords.year,
        formulaCoords.tname,
        filterData,
        searchYear,
        searchTableName,
    ]);
    useEffect(() => {
        // 如果定位有问题,检查这里. 这里采用延时 800ms, 认为表格渲染完成, 进行定位.
        // ps：以前是放在contentReady中，contentReady会比较准，但是会导致滚动条无法继续正常滚动
        setTimeout(async () => {
            if (formulaCoords.rmap &&
                (formulaCoords.year === searchYear || formulaCoords.year === "year") &&
                formulaCoords.tname === searchTableName) {
                await devCellScrollPositionBySelected(devTableRef, formulaCoords.rmap, formulaCoords.cmap, filterData, DataGridOptions.columnWidth);
                console.log("数据定位---单元格标注");
                devCellSelected(devTableRef, formulaCoords.rmap, formulaCoords.cmap, DataGridOptions.columnWidth);
            }
        }, 500);
    }, [
        formulaCoords.rmap,
        formulaCoords.cmap,
        formulaCoords.year,
        formulaCoords.tname,
        filterData,
        searchYear,
        searchTableName,
    ]);
    // 接收父元素通知
    useImperativeHandle(ref, () => {
        return {
            updateSearchCondition: (params) => {
                // 更新搜索条件状态
                const { tname, year, rmap, cmap } = params;
                // TODO 下拉框的取数源在外部传入 ,  useEffect props.baseReportCategoryData 可能会在该函数之后执行。 导致重新重置.
                setTimeout(() => {
                    if (tname) {
                        setSearchTableName(tname);
                    }
                    if (year) {
                        if (year === "year") {
                            // 如果是动态公式, 年度直接重置为本年
                            setSearchYear(consts.ThisYear);
                        }
                        else {
                            setSearchYear(year ? year.toString() : year);
                        }
                    }
                }, 300);
                setFormulaCoords({
                    rmap,
                    cmap,
                    year,
                    tname,
                });
            },
            // 获取当前取数源的表名
            getCurrentTName: () => {
                return searchTableName;
            },
            // 获取当前年
            getCurrentYear: () => {
                return searchYear;
            },
            clearFormula: () => {
                setFormulaCoords({
                    tname: null,
                    rmap: null,
                    cmap: null,
                    year: null,
                });
            },
        };
    });
    // 初始化准备数据
    const initData = async () => {
        await initSearchTableDefaultName();
    };
    // 初始化取数源下拉框数据
    const initSearchTableDefaultName = async () => {
        const baseReportCategoryData = props.baseReportCategoryData;
        const defaultSelectValue = baseReportCategoryData.length > 0 ? baseReportCategoryData[0].value : "";
        // 初始化下拉框值
        setSearchTableName(defaultSelectValue);
    };
    /**
     * 根据搜索条件，加载表格数据
     */
    const initBaseReportData = async () => {
        const devInstance = devTableRef?.current?.instance;
        if (!(props.activeKey === consts.ReportTabKey && devInstance)) {
            return;
        }
        const DataId = await getYears(searchYear);
        const params = {
            tname: searchTableName,
            data_id: DataId,
            dbName: dbname,
            fields: [],
            where: "",
            order: "",
        };
        // 虽然是属于前端过滤, 但是属于通用. 所以当做取数接口的一部分, 根据项目名称搜索
        const projectSearchValue = getProjectSearchValue();
        let { columnData } = await getColumnHeader(params);
        let dataSource = await getTableData(params, projectSearchValue);
        // 根据当前表格定位, 设置 category 数据 ,  category 依赖 tableName 和 当前定位devCoords.
        // formulaCoords 的 rmap 为 null , 说明无表格定位.
        if (formulaCoords.rmap) {
            let rowByRmap = dataSource.find((item) => {
                return item["主键"] === formulaCoords.rmap;
            });
            if (searchTableName === BB_REPORT && rowByRmap) {
                // 如果是报告基础数据,设置为归属表
                setSearchCategory(rowByRmap["所属报表"]);
            }
            else if (searchTableName === CW_KMB && rowByRmap) {
                const kmlx = rowByRmap["科目类型"];
                // 科目明细设置为, 科目类型.
                setSearchCategory(transformKMLXToCategory(kmlx));
            }
        }
        //刷新表格数据
        setBaseReportData({ ...{ dataSource, columns: columnData } });
    };
    /**
     * 将科目类型转换成目前的的前端自定义分类定义;
     * 资产 ， 负债  ， 利润
     */
    function transformKMLXToCategory(kmlx) {
        if (kmlx.includes("资产")) {
            return "资产";
        }
        else if (kmlx.includes("负债")) {
            return "负债";
        }
        else {
            return "利润";
        }
    }
    // 组件事件-------------------------
    // 数据源下拉框
    const baseReportCategoryChange = async (val, item) => {
        setSearchTableName(val);
        // 重置搜索类别 , 如果formulaCoords 不存在, 则该逻辑生效. 否则会在同步表格数据的时候,冲掉此逻辑
        if (val === BB_REPORT) {
            setSearchCategory(fromBaseReportCategoryOption[0].value);
        }
        else {
            setSearchCategory(kmLxOption[0].value);
        }
    };
    // 年度下拉框
    const yearDataChange = (e) => {
        setSearchYear(e.value);
    };
    // 所属报表下拉框
    const fromBaseReportCategoryChange = (e) => {
        setSearchCategory(e.value);
    };
    // 项目搜索
    const projectInputEnter = (e) => {
        initBaseReportData();
    };
    // 刷新列表数据
    const refresh = () => {
        // 按照当前条件进行搜索.
        initBaseReportData();
    };
    // dev表格双击事件
    const devTableDbClick = useCallback((e) => {
        props.generateCustomFormula(e, searchTableName, searchYear, searchCategory);
    }, [searchTableName, searchYear, searchCategory]);
    return (_jsx(_Fragment, { children: _jsxs("div", { children: [_jsxs("div", { className: "flexCon mb-10 f12", children: [_jsxs("div", { className: "flex-start", children: [_jsx("div", { className: "mr-8 nowrap", children: "\u53D6\u6570\u6E90:" }), _jsx("div", { className: "mr-24", id: "self_sty", children: _jsx(Select, { value: searchTableName, style: { width: 180 }, options: props.baseReportCategoryData, onChange: baseReportCategoryChange }) }), _jsxs("div", { style: {
                                        display: "flex",
                                        alignItems: "center",
                                    }, children: [_jsx("div", { className: "mr-8 nowrap", children: "\u5E74\u5EA6:" }), _jsx("div", { className: "custom_curYear", children: _jsx(SelectBox, { disabled: props.dynamic.isDynamic && props.dynamic.dynamicModel, width: 95, dataSource: yearData, value: searchYear, onValueChanged: yearDataChange }) })] }), searchTableName === BB_REPORT ? (_jsxs(_Fragment, { children: [_jsx("div", { style: { marginLeft: 15 }, className: "mr-8 nowrap", children: "\u6240\u5C5E\u62A5\u8868:" }), _jsx("div", { children: _jsx(SelectBox, { width: 120, valueExpr: "value", displayExpr: "label", dataSource: fromBaseReportCategoryOption, value: searchCategory, onValueChanged: fromBaseReportCategoryChange }) })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { style: { marginLeft: 15 }, className: "mr-8 nowrap", children: "\u79D1\u76EE\u7C7B\u578B:" }), _jsx("div", { children: _jsx(SelectBox, { width: 120, valueExpr: "value", displayExpr: "label", dataSource: kmLxOption, value: searchCategory, onValueChanged: fromBaseReportCategoryChange }) })] }))] }), _jsxs("div", { className: "flex-start", children: [_jsx("div", { className: "mr-8 nowrap", children: "\u9879\u76EE\u540D\u79F0:" }), _jsx("div", { children: _jsx(Input, { style: { height: "30px" }, ref: projectSearchInputRef, size: "small", placeholder: "", 
                                        // onChange={this.changeInp1}
                                        // value={this.state.projectName1}
                                        onPressEnter: projectInputEnter, suffix: _jsx(SearchOutlined, { onClick: projectInputEnter }) }) }), _jsx("div", { className: "icon_refresh", onClick: refresh, children: _jsx(CpasIcon, { type: "icon-yuefenzhongzhi" }) })] })] }), _jsx("div", { className: "h200", style: { overflow: "hidden" }, children: _jsx(DevGrid.RangeTap, { dataSource: filterData.dataSource, columns: filterData.columns, keyExpr: "主键", ref: devTableRef, scrolling: DataGridOptions.scrolling, paging: DataGridOptions.paging, showBorders: true, showRowLines: true, sorting: {
                            mode: "none",
                        }, onContentReady: onContentReadyCallBack, onCellDblClick: devTableDbClick, columnWidth: DataGridOptions.columnWidth, 
                        // columnAutoWidth={true}  如果开启这个,1. 会导致定位失败, 得先滚动行,在滚动列才能成功. 无论列的渲染模式是 stand / virtual 2. 严重影响拖拽的交互性能
                        rtlEnabled: false }) })] }) }));
};
const ForwardedBaseReportTabPanel = forwardRef(BaseReportTabPanel);
export default ForwardedBaseReportTabPanel;
